package com.xiaoyu.shenyou.shenyouv1.websocketclient.autorecordclient;

import cn.hutool.json.JSONUtil;

import com.xiaoyu.shenyou.shenyouv1.common.roomname.RoomName;
import com.xiaoyu.shenyou.shenyouv1.common.shenyoucode.ToClientCode;
import com.xiaoyu.shenyou.shenyouv1.common.shenyoucode.ToServerCode;
import com.xiaoyu.shenyou.shenyouv1.common.shenyouentity.betconfig.BetConfig;
import com.xiaoyu.shenyou.shenyouv1.common.shenyouentity.betconfig.RoundInfo;
import com.xiaoyu.shenyou.shenyouv1.common.shenyouurl.ShenyouURL;
import com.xiaoyu.shenyou.shenyouv1.server.RoomWebSocketServer;
import com.xiaoyu.shenyou.shenyouv1.services.PredictionService;
import com.xiaoyu.shenyou.shenyouv1.services.RecordService;
import com.xiaoyu.shenyou.shenyouv1.websocketclient.tocliententity.ToClientEntity;
import com.xiaoyu.shenyou.shenyouv1.websocketclient.toserverentity.Position;
import com.xiaoyu.shenyou.shenyouv1.websocketclient.toserverentity.ToServerEntity;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

@Slf4j
@Component
@Scope("prototype")
public class RecordSocketClient extends WebSocketClient {
    private static boolean startFlag = false;

    @Autowired
    private RecordService recordService;

    @Autowired
    private PredictionService predictionService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    private int games;

    public RecordSocketClient() throws URISyntaxException {
        super(new URI(ShenyouURL.WEBSOCKET_URL));
    }

    public static boolean startFlag() {
        return startFlag;
    }

    @Override
    public void onOpen(ServerHandshake handshake) {
        log.info("websocket客户端和服务器连接成功");
        ToServerEntity toServerEntity = new ToServerEntity();
        ToServerEntity entity = toServerEntity.setCode(ToServerCode.LOGIN).setToken(ShenyouURL.TOKEN);
        this.send(JSONUtil.toJsonStr(entity));
        //打上标记
        startFlag = true;
    }

    @Override
    public void onMessage(String message) {
        ToClientEntity toClientEntity = JSONUtil.toBean(message, ToClientEntity.class);
        if (toClientEntity.getCode() == ToClientCode.GAMES || toClientEntity.getCode() == ToClientCode.KILL_ROOM) {
            //消息转发
            RoomWebSocketServer.getWebSocketMap().entrySet().stream()
                    .distinct()
                    .map(entryEntity -> entryEntity.getValue())
                    .forEach(roomWebSocketServer -> {
                        try {
                            roomWebSocketServer.sendMessage(message);
                        } catch (IOException e) {
                            log.info("websocket消息发送异常，{}", e.getMessage());
                            throw new RuntimeException(e);
                        }
                    });
            if (toClientEntity.getCode() == ToClientCode.GAMES) {
                //写入倒计时缓存,下一期
                RoundInfo roundInfo = JSONUtil.toBean(toClientEntity.getData(), RoundInfo.class);
                redisTemplate.opsForValue().set("time", roundInfo);
                //插入可以下注的标记
                redisTemplate.opsForValue().set("predicted", games + 1);
            }
        }

        if (toClientEntity.getCode() == ToClientCode.AUTH) {
            //登录成功，发送位置信息
            ToServerEntity toServerPosition = new ToServerEntity();
            toServerPosition.setCode(ToServerCode.SEND_POSITION)
                    .setGameType(2)
                    .setUid(ShenyouURL.USER_ID)
                    .setRoomId(0)
                    .setPosition(new Position().setX(50).setY(50));
            this.send(JSONUtil.toJsonStr(toServerPosition));
        }
        if (toClientEntity.getCode() == ToClientCode.BET_CONFIG) {
            //下注配置以及期数
            BetConfig config = JSONUtil.toBean(toClientEntity.getData(), BetConfig.class);
            //期数
            games = config.getRoundInfo().getRound();
        }
        if (toClientEntity.getCode() == ToClientCode.KILL_ROOM) {
            String killRoom = toClientEntity.getMessage();
            int start = killRoom.lastIndexOf("：") + 1;
            String killerName = RoomName.getRoomNameById.get(Integer.parseInt(killRoom.substring(start)));
            log.info("杀手去的房间：{}", killerName);
            recordService.insertRecord(killerName, games);
            predictionService.insertPrediction(killerName, games);
        }
        if (toClientEntity.getCode() == ToClientCode.GAME_OVER) {
            //结束，发送位置信息
            ToServerEntity toServerPosition = new ToServerEntity();
            toServerPosition.setCode(ToServerCode.SEND_POSITION)
                    .setGameType(2)
                    .setUid(ShenyouURL.USER_ID)
                    .setRoomId(0)
                    .setPosition(new Position().setX(50).setY(50));
            this.send(JSONUtil.toJsonStr(toServerPosition));
        }
    }

    /**
     * 失败重试
     *
     * @param code
     * @param reason
     * @param remote
     */
    @Override
    public void onClose(int code, String reason, boolean remote) {
        log.info("websocket客户端退出连接:" + reason);
        startFlag = false;
    }

    /**
     * 失败重试
     *
     * @param ex
     */
    @Override
    public void onError(Exception ex) {
        log.info("websocket客户端和服务器连接发生错误={}", ex.getMessage());
        ex.printStackTrace();
    }

}
